#include "linux/module.h"
#include "linux/init.h"
#include "linux/fs.h"
#include "linux/cdev.h"
#include "linux/kdev_t.h"
#include "linux/uaccess.h"
#include "linux/io.h"
#include "linux/poll.h"
#include "linux/signal.h"


struct chrdev
{
    dev_t dev_num;         // 设备号
    struct cdev cdev_test; // cdev
    struct class *class;   // 设备类
    struct device *device; // 设备
    char kbuf[32];
    int flag;
} dev1;

//=================================================
static int open(struct inode *inode, struct file *file)
{
    file->private_data = &dev1;
    printk(KERN_INFO "打开文件\n");
    return 0;
}
static int release(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "关闭文件\n");
    return 0;
}
static ssize_t read(struct file *file, char __user *buff, size_t size, loff_t *off)
{

    return 0;
}
static ssize_t write(struct file *file, const char __user *buff, size_t size, loff_t *off)
{

    return 0;
}

//=================================================

struct file_operations fops_test = {
    .owner = THIS_MODULE,
    .open = open,
    .release = release,
    .read = read,
    .write = write,
};

static int __init my_driver_init(void)
{
    alloc_chrdev_region(&dev1.dev_num, 0, 1, "atomic_test");
    printk(KERN_INFO "主设备号为:%d,次设备号为:%d\n", MAJOR(dev1.dev_num), MINOR(dev1.dev_num));
    cdev_init(&dev1.cdev_test, &fops_test); // 设备初始化cdev结构体和file_operations关联
    dev1.cdev_test.owner = THIS_MODULE;
    cdev_add(&dev1.cdev_test, dev1.dev_num, 1); // 添加设备
    dev1.class = class_create(THIS_MODULE, "atomic_test_class");
    dev1.device = device_create(dev1.class, NULL, dev1.dev_num, NULL, "atomic_test_drive");
    return 0;
}

static void __exit my_driver_exit(void)
{
    device_destroy(dev1.class, dev1.dev_num);
    class_destroy(dev1.class);
    cdev_del(&dev1.cdev_test);
    unregister_chrdev_region(dev1.dev_num, 1);
}

module_init(my_driver_init);
module_exit(my_driver_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("逮就捕");